package com.tanhua.server;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.commons.utils.Constants;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.dubbo.api.*;
import com.tanhua.exception.BusinessException;
import com.tanhua.interceptor.UserHolder;
import com.tanhua.model.domain.Question;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TanhuaService {
    @DubboReference
    private RecommendUserApi recommendUserApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private QuestionApi questionApi;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Value("${tanhua.default.recommend.users}")
    private String recommends;
    @DubboReference
    private UserLikeApi userLikeApi;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private MessagesService messagesService;
    @DubboReference
    private BaiduServiceApi baiduServiceApi;
    @DubboReference
    private VisitorsApi visitorsApi;
    @DubboReference
    private FriendApi friendApi;


    public TodayBest getBest(Long toUserId) {
        //1、获取用户id
        Long userId = UserHolder.getUserId();
        //2、调用API查询
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1l);
            recommendUser.setScore(99d);
        }
        //3、将RecommendUser转化为TodayBest对象
        UserInfo userInfo = userInfoApi.getById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        //4、返回
        return vo;
    }

    public PageResult recommendation(RecommendUserDto recommendUserDto) {
        //获取用户ID
        Long toUserId = UserHolder.getUserId();
        //分页查询推荐用户
        PageResult pageResult = recommendUserApi.getByToUserId(toUserId, recommendUserDto.getPage(), recommendUserDto.getPagesize());
        //获取推荐用户集合
        List<RecommendUser> items = (List<RecommendUser>) pageResult.getItems();
        if (items == null) {
            return pageResult;
        }
        //获取推荐用户ID
        List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
        //构建用户详情查询条件
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(recommendUserDto.getAge());
        userInfo.setGender(recommendUserDto.getGender());
        userInfo.setCity(recommendUserDto.getCity());
        userInfo.setEducation(recommendUserDto.getEducation());
        //根据推荐用户ID 查询
        Map<Long, UserInfo> userInfoMap = userInfoApi.getByIds(ids, userInfo);
        if (MapUtil.isEmpty(userInfoMap)) {
            return null;
        }
        List<TodayBest> todayBestList = items.stream().map(rec -> {
            UserInfo info = userInfoMap.get(rec.getUserId());
            if (info != null) {
                return TodayBest.init(info, rec);
            }
            return null;
        }).filter(ArrayUtil::isNotEmpty)
                .skip((recommendUserDto.getPage() - 1) * recommendUserDto.getPagesize())
                .limit(recommendUserDto.getPagesize())
                .collect(Collectors.toList());

        if (todayBestList != null) {
            pageResult.setItems(todayBestList);
        }

//        List<TodayBest> list = new ArrayList<>();
//        for (RecommendUser item : items) {
//            UserInfo info = userInfoMap.get(item.getUserId());
//            if(info!=null) {
//                TodayBest vo = TodayBest.init(info, item);
//                list.add(vo);
//
//            }
//        }
//        8、构造返回值
//        pageResult.setItems(list);
        return pageResult;
    }

    /**
     * 根据用户Id查询今日佳人详情
     *
     * @param userId
     * @return
     */
    public TodayBest findById(Long userId) {
        UserInfo userInfo = userInfoApi.getById(userId);
        if (userInfo == null) {
            return null;
        }

        RecommendUser recommendUser = recommendUserApi.getByToUserId(userId, UserHolder.getUserId());
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            Random random = new Random();
            int anInt = random.nextInt(40) + 59;
            recommendUser.setScore(Double.parseDouble(Integer.toString(anInt)));
        }

        //构造访客数据，调用API保存
        Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.save(visitors);




//        //查询redis中是否
//        String key = Constants.USER_LIKE_KEY + UserHolder.getUserId().intValue();
//        Boolean member = redisTemplate.opsForSet().isMember(key,
//                userId.toString());
//
//        if (member) {
//            userInfo.setAlreadyLove(true);
//        }
//        TodayBest todayBest = TodayBest.init(userInfo, recommendUser);

        return TodayBest.init(userInfo, recommendUser);
    }

    public String getStrangerQuestions(Long userId) {
        Question question = questionApi.getByUserId(userId);
        if (question == null) {
            question = new Question();
            question.setTxt("请 sample 介绍一下自己");
        }
        return question.getTxt();
    }

    public void replyQuestions(Long userId, String reply) {
        //构建回答问题的封装
        Long currentUserId = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.getById(currentUserId);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("userId", currentUserId);//此处Id不能是String
        hashMap.put("huanXinId", Constants.HX_USER_PREFIX + currentUserId);
        hashMap.put("nickname", userInfo.getNickname());
        hashMap.put("strangerQuestion", getStrangerQuestions(userId));
        hashMap.put("reply", reply);
        //解析成JsonString以便前端解析
        String jsonString = JSON.toJSONString(hashMap);

        //向用户发送答案信息
        Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, jsonString);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    /**
     * 根据用户Id查询推荐用户集合
     *
     * @return
     */
    public List<TodayBest> queryCardsList() {
        //查询推荐用户，排除喜欢和不喜欢
        List<RecommendUser> recommendUsers = recommendUserApi.queryCardsList(UserHolder.getUserId(), 10);
        //2、判断数据是否存在，如果不存在，构造默认数据 1,2,3,yml配置文件构造默认推荐
        if (CollUtil.isEmpty(recommendUsers)) {
            recommendUsers = new ArrayList<>();
            String[] userIdS = recommends.split(",");
            for (String userId : userIdS) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(userId));
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                recommendUsers.add(recommendUser);
            }
        }
        //构造推荐用户详细信息
        List<Long> userId = CollUtil.getFieldValues(recommendUsers, "userId", Long.class);
        Map<Long, UserInfo> userInfoMap = userInfoApi.getByIds(userId, null);

        List<TodayBest> todayBestList = recommendUsers.stream().map((recommendUser -> {
            UserInfo userInfo = userInfoMap.get(recommendUser.getUserId());
            if (userInfo != null) {
                return TodayBest.init(userInfo, recommendUser);
            }
            return null;
        })).filter(Objects::nonNull).collect(Collectors.toList());

        return todayBestList;
    }

    public void likeUser(Long likeUserId) {
        //保存当前用户喜欢用户
        Boolean aBoolean = userLikeApi.saveOrUpdate(UserHolder.getUserId(), likeUserId, true);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
        //保存数据到Redis，先删除redis数据
        redisTemplate.opsForSet().remove(
                Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId().toString(),
                likeUserId.toString()
        );
        redisTemplate.opsForSet().add(
                Constants.USER_LIKE_KEY + UserHolder.getUserId().toString(),
                likeUserId.toString()
        );
        //判断对方是否喜欢
        if (isLike(likeUserId, UserHolder.getUserId())) {
            //添加成好友
            messagesService.contactsTo(likeUserId);
        }
    }

    public void dislikeUser(Long likeUserId) {
        Boolean aBoolean = userLikeApi.saveOrUpdate(UserHolder.getUserId(), likeUserId, false);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
        //如果相互喜欢有好友信息，要解除好友关系
        if (isLike(likeUserId, UserHolder.getUserId())) {
            messagesService.unContactsTo(likeUserId);
        }

        friendApi.unContactsTo(UserHolder.getUserId(), likeUserId);

        redisTemplate.opsForSet().remove(
                Constants.USER_LIKE_KEY + UserHolder.getUserId().toString(),
                likeUserId.toString());
        redisTemplate.opsForSet().add(
                Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId().toString(),
                likeUserId.toString()
        );

    }


    private boolean isLike(Long likeUserId, Long userId) {
        Boolean member = redisTemplate.opsForSet().isMember(
                Constants.USER_LIKE_KEY + likeUserId.toString(),
                userId.toString()
        );
        if (member == null) {
            return false;
        }
        return member;
    }

    /**
     * 查询当前用户附近的人
     *
     * @param gender   性 别
     * @param distance 距离(m)
     * @return List<NearUserVo>
     */
    public List<NearUserVo> getNearUser(String gender, String distance) {
//        //查询附近的人,注意UserLocation不能返回，因为有Location这个字段，该字段无法序列化
//        List<UserLocation> userLocations = baiduServiceApi.getNearUser(UserHolder.getUserId(), distance);
//        //提取UserId
//        List<Long> userIds = CollUtil.getFieldValues(userLocations, "userId", Long.class);

        //1、调用API查询附近的用户（返回的是附近的人的所有用户id，包含当前用户的id）
        List<Long> userIds = baiduServiceApi.queryNearUser(UserHolder.getUserId(), Double.valueOf(distance));

        //2、判断集合是否为空
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }

        //查询用户详情,构造过滤条件
        UserInfo userInfo1 = new UserInfo();
//        userInfo1.setGender(gender);
        userInfo1.setGender("woman");
        Map<Long, UserInfo> userInfoMap = userInfoApi.getByIds(userIds, userInfo1);
        return userIds.stream().map((userId) -> {
            UserInfo userInfo = userInfoMap.get(userId);
            if (userInfo != null) {
                return NearUserVo.init(userInfo);
            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList());


    }
}
